package org.subatu.orm.entity;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.subatu.orm.annotation.TableId;
import org.subatu.orm.annotation.TableLogic;
import org.subatu.orm.annotation.Version;
import org.subatu.orm.type.IdType;
import org.subatu.orm.util.ClassUtil;
import org.subatu.orm.util.FieldUtils;
import org.subatu.orm.util.SnowflakeIdWorker;
import org.subatu.orm.util.SqlUtil;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 分解entity转化的sql
 *
 * @author 冯晓东
 */
public class EntityBean<T> {
    private static final Logger logger = LoggerFactory.getLogger(EntityBean.class);

    // 属于哪个类
    private Class<T> clazz;
    private String tableName;

    // 各种属性
    private List<Field> idFieldList = new ArrayList<>();
    private Field versionField;
    private Field tableLogicField;
    private List<Field> allFieldList = new ArrayList<>();
    private List<Field> allUpdateFieldList = new ArrayList<>();

    private String insertSql;
    private String updateSql;
    private String deleteSql;
    private String deleteRealSql;
    private String selectByIdSql;

    public EntityBean(Class<T> clazz) {
        this.clazz = clazz;
    }

    // 初始化解析
    public void init() {
        if (this.tableName != null) {
            logger.warn("EntitySql:{}已初始化，防止重复调用！", clazz.getName());
            return;
        }
        // 初始表结构
        this.tableName = SqlUtil.getTableName(clazz);

        // 包含父类的所有字段
        Field[] fields = clazz.getDeclaredFields();
        allFieldList.clear();
        for (Field field : fields) {
            // 1.判断是否 不映射
            if (FieldUtils.isNotField(field) == true) {
                continue;
            }
            // 2.加入到队列
            allFieldList.add(field);


            // 3.判断是否id,version,logic
            TableId tableId = field.getAnnotation(TableId.class);
            if (tableId != null) {
                idFieldList.add(field);
            }
            Version version = field.getAnnotation(Version.class);
            if (version != null) versionField = field;
            TableLogic tableLogic = field.getAnnotation(TableLogic.class);
            if (tableLogic != null) tableLogicField = field;

        }//# for


    }//# init

    public String getInsertSql() {
        if (insertSql != null) {
            return insertSql;
        }
        insertSql = SqlUtil.makeInsertSql(this);

        return insertSql;
    }

    public String getUpdateSql() {
        if (updateSql != null) {
            return updateSql;
        }
        updateSql = SqlUtil.makeUpdateSql(this);
        return updateSql;
    }

    public String getDeleteSql() {
        if (deleteSql != null) {
            return deleteSql;
        }
        deleteSql = SqlUtil.makeDeleteSql(this);
        return deleteSql;
    }

    public String getDeleteRealSql() {
        if (deleteRealSql != null) {
            return deleteRealSql;
        }
        deleteRealSql = SqlUtil.makeDeleteRealSql(this);
        return deleteRealSql;
    }

    public String getSelectByIdSql() {
        if (selectByIdSql != null) {
            return selectByIdSql;
        }
        selectByIdSql = SqlUtil.makeSelectByIdSql(this);
        return selectByIdSql;
    }

    // ===================== getter 函数 ===============================================
    public Class<T> getClazz() {
        return clazz;
    }

    public String getTableName() {
        return tableName;
    }

    public List<Field> getIdFieldList() {
        return idFieldList;
    }

    public Field getVersionField() {
        return versionField;
    }

    public Field getTableLogicField() {
        return tableLogicField;
    }

    public List<Field> getAllFieldList() {
        return allFieldList;
    }

    // 预先设置id的值
    public <T> void initIdValues(T entity) {
        for (Field idField : this.idFieldList) {
            this.randomId(entity, idField);
        }
    }

    // 随机生成一个id
    private void randomId(Object entity, Field idField) {
        // 如果有值,直接跳过
        if (ClassUtil.getFieldValue(entity, idField) != null) {
            return;
        }

        TableId annotation = idField.getAnnotation(TableId.class);
        IdType type = annotation.type();
        // AUTO(0), NONE(1), INPUT(2), ASSIGN_ID(3), ASSIGN_UUID(4);
        Object idValue = switch (type) {
            case ASSIGN_ID -> SnowflakeIdWorker.getInstance().nextId() + "";
            case ASSIGN_UUID -> UUID.randomUUID().toString();
            default -> null;
        };

        ClassUtil.setFieldValue(entity, idField, idValue);
    }

    public boolean isGeneralColumn(Field field) {
        if (field.equals(tableLogicField)) {
            return false;
        }
        if (idFieldList.contains(field)) {
            return false;
        }
        return true;
    }

    // 获取更新数据的 field
    public List<Field> getAllUpdateFieldList() {
        if (allUpdateFieldList.size() > 0) {
            return allUpdateFieldList;
        }
        // 1.先加入普通字段
        for (Field field : allFieldList) {
            if (!this.isGeneralColumn(field)) {
                continue;
            }
            allUpdateFieldList.add(field);
        }
        // 2. 加入id , logic, version
        allUpdateFieldList.addAll(idFieldList);
        // if (tableLogicField != null) { // 已经写死0 ,不需要设置了
        //     allUpdateFieldList.add(tableLogicField);
        // }
        if (versionField != null) {
            allUpdateFieldList.add(versionField);
        }
        return allUpdateFieldList;
    }
}
